#ifndef TRANSACTION_HH
#define TRANSACTION_HH

#include <string>
#include <sstream>
#include <chrono>
#include <ctime>
#include <iomanip>
#include "Utils.hh"

namespace BankSystem
{
    enum class TransactionType
    {
        TRANSFER,
        DEPOSIT,
        WITHDRAW
    };

    class Transaction
    {
    private:
        std::string transactionId;
        TransactionType type;
        std::string sourceAccountId;
        std::string destinationAccountId;
        double amount;
        std::string date;
        std::string note;

        // 生成唯一的交易ID
        std::string generateTransactionId()
        {
            auto now = std::chrono::system_clock::now();
            auto nowTimeT = std::chrono::system_clock::to_time_t(now);
            auto nowMs = std::chrono::duration_cast<std::chrono::milliseconds>(
                              now.time_since_epoch()) % 1000;

            std::stringstream ss;
            ss << "TXN" << std::put_time(std::localtime(&nowTimeT), "%Y%m%d%H%M%S")
               << std::setfill('0') << std::setw(3) << nowMs.count();

            return ss.str();
        }

        // 获取当前日期和时间
        std::string getCurrentDateTime()
        {
            auto now = std::chrono::system_clock::now();
            auto nowTimeT = std::chrono::system_clock::to_time_t(now);

            std::stringstream ss;
            ss << std::put_time(std::localtime(&nowTimeT), "%Y-%m-%d %H:%M:%S");

            return ss.str();
        }

    public:
        // 构造函数 - 转账
        Transaction(const std::string &source, const std::string &destination,
                    double txnAmount, const std::string &txnNote = "")
            : type(TransactionType::TRANSFER),
              sourceAccountId(source),
              destinationAccountId(destination),
              amount(txnAmount),
              note(txnNote)
        {
            transactionId = generateTransactionId();
            date = getCurrentDateTime();
        }

        // 构造函数 - 存款或取款
        Transaction(TransactionType txnType, const std::string &accountId,
                    double txnAmount, const std::string &txnNote = "")
            : type(txnType), amount(txnAmount), note(txnNote)
        {
            transactionId = generateTransactionId();
            date = getCurrentDateTime();

            if (txnType == TransactionType::DEPOSIT)
            {
                destinationAccountId = accountId;
                sourceAccountId = "CASH";
            }
            else if (txnType == TransactionType::WITHDRAW)
            {
                sourceAccountId = accountId;
                destinationAccountId = "CASH";
            }
        }
        
        // 构造函数 - 用于从文件加载交易数据
        Transaction(const std::string &id, TransactionType txnType, 
                    const std::string &source, const std::string &destination,
                    double txnAmount, const std::string &txnDate, const std::string &txnNote = "")
            : transactionId(id),
              type(txnType),
              sourceAccountId(source),
              destinationAccountId(destination),
              amount(txnAmount),
              date(txnDate),
              note(txnNote)
        {
        }

        // Getters
        std::string getTransactionId() const { return transactionId; }
        TransactionType getType() const { return type; }
        std::string getSourceAccountId() const { return sourceAccountId; }
        std::string getDestinationAccountId() const { return destinationAccountId; }
        double getAmount() const { return amount; }
        std::string getDate() const { return date; }
        std::string getNote() const { return note; }

        // 获取交易详情字符串
        std::string getDetails() const
        {
            std::stringstream ss;
            ss << "Transaction ID: " << transactionId << std::endl;
            ss << "Date: " << date << std::endl;

            switch (type)
            {
            case TransactionType::TRANSFER:
                ss << "Type: Transfer" << std::endl;
                ss << "From: " << sourceAccountId << std::endl;
                ss << "To: " << destinationAccountId << std::endl;
                break;
            case TransactionType::DEPOSIT:
                ss << "Type: Deposit" << std::endl;
                ss << "To: " << destinationAccountId << std::endl;
                break;
            case TransactionType::WITHDRAW:
                ss << "Type: Withdrawal" << std::endl;
                ss << "From: " << sourceAccountId << std::endl;
                break;
            }

            ss << "Amount: " << Utils::formatCurrency(amount) << std::endl;
            
            if (!note.empty())
            {
                ss << "Note: " << note << std::endl;
            }

            return ss.str();
        }
    };
}

#endif // TRANSACTION_HH